package com.yang.news.aspect;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.yang.news.dao.entity.VisitLog;
import com.yang.news.service.VisitLogService;
import com.yang.news.util.AddressUtil;
import com.yang.news.util.HttpContextUtil;
import com.yang.news.util.IPUtil;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.Serializable;
import java.lang.reflect.Method;
import java.util.*;

import static com.yang.news.util.DeviceUtil.isFromMobile;

/**
 * @author Billyang
 * @date 2024/11/29 11:55
 */
@Component
@Aspect
@Slf4j
public class VisitLogAspect {
    @Autowired
    private VisitLogService visitLogService;

    @Around("@annotation(com.yang.news.aspect.IPLog)")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        log.info("visitLog aspect start.........");
        //获取request
        HttpServletRequest request = HttpContextUtil.getHttpServletRequest();
        // 请求的类名
        MethodSignature signature = (MethodSignature)joinPoint.getSignature();
        Method method = signature.getMethod();
        String className = joinPoint.getTarget().getClass().getName();
        // 请求的方法名
        String methodName = signature.getName();
        String ip = IPUtil.getRemoteIP(request);
        String address = AddressUtil.getCityInfo(ip);
        VisitLog visitLog = VisitLog.builder().deviceType(isFromMobile(request) ? "手机" : "电脑").method(
                className + "." + methodName + "()").ip(ip).address(address).build();
        // 请求的方法参数值
        Object[] args = joinPoint.getArgs();
        // 请求的方法参数名称
        LocalVariableTableParameterNameDiscoverer u = new LocalVariableTableParameterNameDiscoverer();
        String[] paramNames = u.getParameterNames(method);
        if (args != null && paramNames != null) {
            // 创建 key-value 映射用于生成 JSON 字符串
            Map<String, Object> paramMap = new LinkedHashMap<>();
            for (int i = 0; i < paramNames.length; i++) {
                if (args[i] instanceof HttpServletRequest || args[i] instanceof HttpServletResponse) {
                    continue;
                }
                paramMap.put(paramNames[i], args[i]);
            }
            // 使用 Fastjson 将参数映射转换为 JSON 字符串
            String paramsJson = JSON.toJSONString(paramMap);
            visitLog.setParams(paramsJson);
        }
        long beginTime = System.currentTimeMillis();
        Object proceed = joinPoint.proceed();
        long end = System.currentTimeMillis();
        visitLog.setTime((int)(end - beginTime));
        visitLogService.save(visitLog);
        return proceed;
    }

}
